#include <iostream>
#include <algorithm>
#include <string.h>
#include <assert.h>

using namespace std;

namespace my
{
	class string
	{
	public:
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			//cout << "string(char* str)" << endl;
			//cout << "构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		// s1.swap(s2)
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}
		// 拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 深拷贝" << endl;
			string tmp(s._str);
			swap(tmp);
		}
		// 赋值重载
		string& operator=(const string& s)
		{
			cout << "string& operator=(string s) -- 深拷贝" << endl;
			string tmp(s);
			swap(tmp);
			return *this;
		}
		 // 移动构造
		 string(string&& s)
			 :_str(nullptr)
			 , _size(0)
			 , _capacity(0)
		 {
			 cout << "string(string&& s) -- 移动语义" << endl;
			 swap(s);
		 }
		 // 移动赋值
		 string& operator=(string&& s)
		 {
			 cout << "string& operator=(string&& s) -- 移动语义" << endl;
			 swap(s);
			 return *this;
		 }
		 ~string()
		 {
			 delete[] _str;
			 _str = nullptr;
		 }
		 char& operator[](size_t pos)
		 {
			 assert(pos < _size);
			 return _str[pos];
		 }
		 void reserve(size_t n)
		 {
			 if (n > _capacity)
			 {
				 char* tmp = new char[n + 1];
				 strcpy(tmp, _str);
				 delete[] _str;
				 _str = tmp;
				 _capacity = n;
			 }
		 }
		 void push_back(const char& ch)
		 {
             cout << "push_back正常尾插" << endl;
			 if (_size >= _capacity)
			 {
				 size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				 reserve(newcapacity);
			 }
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		 }
         void push_back(char&& ch)
         {
             cout << "push_back移动尾插" << endl;
			 if (_size >= _capacity)
			 {
				 size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				 reserve(newcapacity);
			 }
            
             ++ _size;
             ::swap(_str[_size - 1], ch);
             _str[_size] = '\0';
         }
		 //string operator+=(char ch)
		 string& operator+=(char ch)
		 {
			 push_back(ch);
			 return *this;
		 }
		 const char* c_str() const
		 {
			 return _str;
		 }
	private:
		char* _str;
		size_t _size;
		size_t _capacity; // 不包含最后做标识的\0
	};
}

my::string mto_string(int value)
{
	bool flag = true;
	if (value < 0)
	{
		flag = false;
		value = 0 - value;
	}
	my::string str;
	while (value > 0)
	{
		int x = value % 10;
		value /= 10;
		str += ('0' + x);
	}
	if (flag == false)
	{
		str += '-';
	}

	std::reverse(str.begin(), str.end());
	return str;
}

my::string func(const char* str)
{
	my::string s(str);
	return s;
}

void test2()
{
	my::string ret1 = func("hello");
	//my::string ret2 = func("world");
}

void test3()
{
    my::string s;
    s = func("hello");
}

void test1()
{
	//my::string s1("hello");
	//cout << s1.c_str() << endl;

	my::string s1("hello");
	my::string s2(s1);
	cout << endl << endl;

	//my::string s3(my::string("hallo world"));

	my::string s3(move(s1));
}

void test4()
{
    my::string s;
    char ch = 'b';
    s.push_back(ch);

    cout << endl;

    s.push_back('a');
}

int main()
{
	//test1();
	//test2();
    
    //test3();
    
    test4();

	//int a = 0;
	//cout << a << ' ' << &a << endl;
	//int&& ra = move(a);

	//ra = 10;
	//cout << a << ' ' << &ra << endl;

	//int&& rr = 10;
	//cout << rr << ' ' <<  & rr << endl;

	//double b1 = 1.1, b2 = 2.2;
	/*double&& b = b1 + b2;
	cout << b1 + b2 << endl;
	cout << b << endl;*/

	//double addb = b1 + b2;

	//double&& bb = b1 + b2;
	//const double&& bb1 = b1 + b2;
	//double&& bb2 = move(addb);
	//cout << bb1 << ' ' << &bb1 << endl;
	//cout << bb << ' '  << &bb << endl;
	//bb = 10.1;
	//cout << bb1 << ' ' << &bb1 << endl;
	//cout << bb << ' ' << &bb << endl;

	//cout << endl;
	//int&& intr = 10 + 20;
	//cout << intr << ' ' << &intr << endl;

	//const int& a = 10;
	//cout << a << ' ' << &a << endl;

	//int&& a = 10;
	//cout << a << ' ' << &a << endl;
	//a = 20;
	//cout << a << ' ' << &a << endl;

	return 0;
 }
